package edu.hawaii.duedates.book;

import java.util.Calendar;
import java.util.Locale;


/**
 * The Book Class implements the IBook interface.  A book is comprised of a title and a due date.
 * 
 * @author Ronn Reeves and Robin E. Raqueno
 */
public class Book implements IBook {
  
  /** The due date for the book. */
  private Calendar dueDate;
  
  /** The library the book belongs to. */
  private String library;
  
  
  /**  The book title.  */
  private String title;


  /**
   * Creates a book object with the given title and due date.
   * 
   * @param title  The book title.
   * @param dueDate  The due date of the book.
   * @param library The library the book belongs to.
   */
  public Book(String title, String dueDate, String library) {
    this.formatTitle(title);
    this.formatDueDate(dueDate);
    this.library = library;
  }

  
  /**
   * Compares this book's due date to the caller's book's due date.
   * 
   * @param book The book to be compared.
   * @return The sort order compared to this book.
   */
  public int compareByDate(Book book) {
    Calendar s1 = book.getDueDate();
    Calendar s2 = this.dueDate;
    return s2.compareTo(s1);
  }


  /**
   * Compares this book's library to the calling book's library.
   * 
   * @param book The book to be compared.
   * @return The sort order compared to this book.
   */
  public int compareByLibrary(Book book) {
    return library.compareToIgnoreCase(book.getLibrary());
  }


  /**
   * Converts the calendar date to a string for display.
   * 
   * @return String The date to be displayed. 
   */
  public String convertDate() {
    return String.format(Locale.US, "%tD", this.dueDate);
  }


  /**
   * Converts the date string to a calendar date.
   * 
   * @param date  The string date to be converted.
   * @return Calendar The calendar date.
   */
  private Calendar convertDate(String date) {
    Calendar cal = Calendar.getInstance(Locale.US);
    int month = Integer.parseInt(date.substring(0, 2));
    int day = Integer.parseInt(date.substring(3, 5));
    int year = Integer.parseInt(date.substring(date.length() - 2, 8));
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DAY_OF_MONTH, day);
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    //String dd = month + "-" + day + "-" + year;
    cal.set(year, month - 1, day, 0, 0, 0);
    return cal;
  }


  /**
   * Standardizes the due date of this book.
   * 
   * @param  dueDate  The due date of the book.
   */
  private void formatDueDate(String dueDate) {
    if (dueDate.length() > 10) {
      String s1 = dueDate;
      String endOfDueDate = dueDate.substring(dueDate.length() - 4);
      if (endOfDueDate.contains(":")) {
        int lastSpace = dueDate.lastIndexOf(' ');
        s1 = dueDate.substring(lastSpace - 8, lastSpace);
      }
      else {
        s1 = dueDate.substring(dueDate.length() - 8);  
      }
      
      this.dueDate = convertDate(s1);
    }
    else {
      this.dueDate = convertDate(dueDate.substring(0, 6) + dueDate.substring(8, 10));
    }
  }


  /**
   * Strips up to 75 characters of the title of this book from extra data in the title string.
   * 
   * @param title  The book title (up to 75 characters).
   */
  private void formatTitle(String title) {
    String s1 = title;
    String location = "Location:";
    
    if (s1.contains(location)) {
      boolean hasDelimiter = s1.contains("/");
      if (hasDelimiter) {
        // The title lies between the first occurrence of "  " and the last occurrence of "/"
        // in the displayed out of the University of Hawaii website.
        if (s1.indexOf("  ") < s1.indexOf('/')) {
          s1 = s1.substring(s1.indexOf("  ") + 2, s1.lastIndexOf('/') - 1);
        }
      
        // The title lies between the start of the title through the last occurrence of "/"
        // in the displayed out of the University of Hawaii website.
        else {
          s1 = s1.substring(0, s1.lastIndexOf('/') - 1);
        }
      }
      
      else {
        // The title lies between the first occurrence of "   " and the last occurrence of 
        // "Location:" in the displayed out of the University of Hawaii website.
        if ((s1.indexOf("   ") + 3) < s1.indexOf(location)) {
          s1 = s1.substring(s1.indexOf("   ") + 3, s1.lastIndexOf(location));
        }
      
        // The title lies between the start of the title through the last occurrence of
        // "Location:" in the displayed out of the University of Hawaii website.
        else {
          s1 = s1.substring(0, s1.lastIndexOf(location));
        }
      }
    }
    
    if (s1.length() > 75) {
      this.title = s1.substring(0, 75);
    }
    else {
      this.title = s1;
    }
  }


  /**
   * Returns the due date for this book.
   *
   * @return Date  The due date for the book.
   */
  public Calendar getDueDate() {
    return this.dueDate;
  }


  /**
   * Returns the library the book is from.
   * 
   * @return Library  The library the book is from.
   */
  public String getLibrary() {
    return this.library;
  }

  
  /**
   * Returns the title of this book.  
   *
   * @return String  The book title.
   */
  public String getTitle() {
    return this.title;
  }


  /**
   * Sets the due date of this book.  
   * 
   * @param  dueDate  The due date of the book.
   */
  public void setDueDate(String dueDate) {
    this.formatDueDate(dueDate);
  }


  /**
   * Sets the library the book is from.
   * 
   * @param library  The library the book is from.
   */
  public void setLibrary(String library) {
    this.library = library;
  }


  /**
   * Sets the title of this book.
   * 
   * @param title  The book title.
   */
  public void setTitle(String title) {
    this.formatTitle(title);
  }


  /**
   * Returns the title of this book.  
   *
   * @return String  The book title.
   */
  public String toString() {
    return this.getTitle();
  }
}